/**
 * MQTT通信模块
 * 用于与硬件设备进行数据交互
 */

// 引入MQTT库 (需要先安装: npm install mqtt)
// 注意：微信小程序需要使用支持小程序的MQTT库，如 paho-mqtt
// import Paho from '../miniprogram_npm/paho-mqtt/index.js'

// 临时使用WebSocket模拟MQTT功能
// 实际项目中请使用专门的小程序MQTT库
const Paho = {
  MQTT: {
    Client: class MockMQTTClient {
      constructor(host, port, clientId) {
        this.host = host
        this.port = port
        this.clientId = clientId
        this.connected = false
      }
      
      connect(options) {
        console.log('模拟MQTT连接:', this.host)
        setTimeout(() => {
          if (options.onSuccess) {
            this.connected = true
            options.onSuccess()
          }
        }, 1000)
      }
      
      subscribe(topic, options = {}) {
        console.log('模拟订阅主题:', topic)
        if (options.onSuccess) {
          options.onSuccess()
        }
      }
      
      send(message) {
        console.log('模拟发送消息:', message)
      }
      
      disconnect() {
        this.connected = false
        console.log('模拟断开MQTT连接')
      }
    },
    Message: class MockMessage {
      constructor(payload) {
        this.payloadString = payload
        this.destinationName = ''
        this.qos = 0
        this.retained = false
      }
    }
  }
}

class MQTTManager {
  constructor() {
    this.client = null
    this.isConnected = false
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    
    // MQTT配置 - 请根据您的MQTT服务器配置修改
    this.config = {
      host: 'your-mqtt-broker.com',  // MQTT服务器地址
      port: 8083,                    // WebSocket端口 (通常是8083)
      clientId: `miniprogram_${Math.random().toString(16).substr(2, 8)}`,
      username: 'your_username',      // 如果需要认证
      password: 'your_password',      // 如果需要认证
      keepAliveInterval: 60,          // 心跳间隔(秒)
      timeout: 10,                    // 连接超时(秒)
      useSSL: true                    // 是否使用SSL
    }
    
    // 订阅的主题
    this.topics = {
      ALARM_DATA: 'school/alarm/data',           // 接收报警数据
      DEVICE_STATUS: 'school/device/status',     // 设备状态
      AUDIO_ANALYSIS: 'school/audio/analysis',   // 音频分析结果
      LOCATION_DATA: 'school/location/data'      // 位置数据
    }
    
    // 发布的主题
    this.publishTopics = {
      COMMAND: 'school/command',                 // 发送命令给硬件
      CONFIG: 'school/config',                   // 配置参数
      ACK: 'school/ack'                         // 确认消息
    }
  }

  /**
   * 连接MQTT服务器
   */
  connect() {
    return new Promise((resolve, reject) => {
      try {
        // 创建MQTT客户端
        this.client = new Paho.MQTT.Client(
          this.config.host,
          this.config.port,
          this.config.clientId
        )
        
        // 设置回调函数
        this.client.onConnectionLost = this.onConnectionLost.bind(this)
        this.client.onMessageArrived = this.onMessageArrived.bind(this)
        
        // 连接选项
        const connectOptions = {
          timeout: this.config.timeout,
          keepAliveInterval: this.config.keepAliveInterval,
          useSSL: this.config.useSSL,
          userName: this.config.username,
          password: this.config.password,
          onSuccess: () => {
            console.log('MQTT连接成功')
            this.isConnected = true
            this.reconnectAttempts = 0
            this.subscribeTopics()
            resolve(true)
          },
          onFailure: (error) => {
            console.error('MQTT连接失败:', error)
            this.isConnected = false
            reject(error)
          }
        }
        
        // 开始连接
        this.client.connect(connectOptions)
        
      } catch (error) {
        console.error('MQTT连接异常:', error)
        reject(error)
      }
    })
  }

  /**
   * 订阅主题
   */
  subscribeTopics() {
    Object.values(this.topics).forEach(topic => {
      this.client.subscribe(topic, {
        qos: 1,  // 服务质量等级
        onSuccess: () => {
          console.log(`订阅主题成功: ${topic}`)
        },
        onFailure: (error) => {
          console.error(`订阅主题失败: ${topic}`, error)
        }
      })
    })
  }

  /**
   * 连接丢失处理
   */
  onConnectionLost(responseObject) {
    console.log('MQTT连接丢失:', responseObject.errorMessage)
    this.isConnected = false
    
    // 尝试重连
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++
      console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`)
      
      setTimeout(() => {
        this.connect().catch(error => {
          console.error('重连失败:', error)
        })
      }, 5000 * this.reconnectAttempts) // 递增延迟
    } else {
      console.error('达到最大重连次数，停止重连')
      // 通知界面连接失败
      this.notifyConnectionStatus(false)
    }
  }

  /**
   * 消息到达处理
   */
  onMessageArrived(message) {
    console.log('收到MQTT消息:', message.destinationName, message.payloadString)
    
    try {
      const data = JSON.parse(message.payloadString)
      
      // 根据主题分发消息
      switch (message.destinationName) {
        case this.topics.ALARM_DATA:
          this.handleAlarmData(data)
          break
        case this.topics.DEVICE_STATUS:
          this.handleDeviceStatus(data)
          break
        case this.topics.AUDIO_ANALYSIS:
          this.handleAudioAnalysis(data)
          break
        case this.topics.LOCATION_DATA:
          this.handleLocationData(data)
          break
        default:
          console.log('未知主题消息:', message.destinationName)
      }
    } catch (error) {
      console.error('解析MQTT消息失败:', error)
    }
  }

  /**
   * 处理报警数据
   */
  handleAlarmData(data) {
    console.log('收到报警数据:', data)
    
    // 创建报警记录
    const alarmRecord = {
      id: this.generateId(),
      timestamp: data.timestamp || Date.now(),
      type: data.type || 'unknown',
      level: data.level || 'medium',
      location: data.location || {},
      deviceId: data.deviceId,
      audioData: data.audioData || {},
      evidence: data.evidence || {},
      status: 'active',
      handled: false
    }
    
    // 保存到本地存储
    this.saveAlarmRecord(alarmRecord)
    
    // 通知界面更新
    this.notifyAlarmReceived(alarmRecord)
    
    // 发送确认消息
    this.sendAck(data.messageId)
  }

  /**
   * 处理设备状态
   */
  handleDeviceStatus(data) {
    console.log('设备状态更新:', data)
    
    // 更新设备状态到全局数据
    const app = getApp()
    if (app.globalData) {
      app.globalData.deviceStatus = {
        ...app.globalData.deviceStatus,
        isConnected: data.online || false,
        battery: data.battery || 0,
        signal: data.signal || 0,
        lastUpdate: Date.now()
      }
    }
    
    // 通知界面更新
    this.notifyDeviceStatusChanged(data)
  }

  /**
   * 处理音频分析结果
   */
  handleAudioAnalysis(data) {
    console.log('音频分析结果:', data)
    
    // 更新音频数据到全局
    const app = getApp()
    if (app.globalData) {
      app.globalData.audioData = {
        soundLevel: data.decibel || 0,
        soundType: data.type || 'normal',
        frequency: data.frequency || 0,
        alert: data.alert || false,
        confidence: data.confidence || 0,
        timestamp: data.timestamp || Date.now()
      }
    }
    
    // 通知界面更新
    this.notifyAudioDataUpdated(data)
  }

  /**
   * 处理位置数据
   */
  handleLocationData(data) {
    console.log('位置数据更新:', data)
    
    // 保存位置信息
    const app = getApp()
    if (app.globalData) {
      app.globalData.locationData = {
        latitude: data.latitude || 0,
        longitude: data.longitude || 0,
        accuracy: data.accuracy || 0,
        address: data.address || '',
        timestamp: data.timestamp || Date.now()
      }
    }
  }

  /**
   * 发布消息
   */
  publish(topic, payload, options = {}) {
    if (!this.isConnected || !this.client) {
      console.error('MQTT未连接，无法发送消息')
      return false
    }
    
    try {
      const message = new Paho.MQTT.Message(JSON.stringify(payload))
      message.destinationName = topic
      message.qos = options.qos || 1
      message.retained = options.retained || false
      
      this.client.send(message)
      console.log('MQTT消息发送成功:', topic, payload)
      return true
    } catch (error) {
      console.error('MQTT消息发送失败:', error)
      return false
    }
  }

  /**
   * 发送确认消息
   */
  sendAck(messageId) {
    this.publish(this.publishTopics.ACK, {
      messageId: messageId,
      timestamp: Date.now(),
      status: 'received'
    })
  }

  /**
   * 发送命令给硬件
   */
  sendCommand(command, params = {}) {
    return this.publish(this.publishTopics.COMMAND, {
      command: command,
      params: params,
      timestamp: Date.now(),
      messageId: this.generateId()
    })
  }

  /**
   * 保存报警记录
   */
  saveAlarmRecord(record) {
    try {
      let records = wx.getStorageSync('alarmRecords') || []
      records.unshift(record) // 添加到开头
      
      // 限制最大记录数
      if (records.length > 1000) {
        records = records.slice(0, 1000)
      }
      
      wx.setStorageSync('alarmRecords', records)
      console.log('报警记录保存成功:', record.id)
    } catch (error) {
      console.error('保存报警记录失败:', error)
    }
  }

  /**
   * 生成唯一ID
   */
  generateId() {
    return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  }

  /**
   * 通知方法 - 这些方法会被页面重写
   */
  notifyConnectionStatus(isConnected) {
    // 页面可以重写此方法来处理连接状态变化
    console.log('连接状态变化:', isConnected)
  }

  notifyAlarmReceived(alarmRecord) {
    // 页面可以重写此方法来处理新报警
    console.log('收到新报警:', alarmRecord)
  }

  notifyDeviceStatusChanged(status) {
    // 页面可以重写此方法来处理设备状态变化
    console.log('设备状态变化:', status)
  }

  notifyAudioDataUpdated(data) {
    // 页面可以重写此方法来处理音频数据更新
    console.log('音频数据更新:', data)
  }

  /**
   * 断开连接
   */
  disconnect() {
    if (this.client && this.isConnected) {
      this.client.disconnect()
      this.isConnected = false
      console.log('MQTT连接已断开')
    }
  }
}

// 创建单例
const mqttManager = new MQTTManager()

export default mqttManager 